package com.shortlink.pojos.dto.dataobject;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.shortlink.common.constants.AppHttpCodeEnum;
import com.shortlink.common.constants.IErrorCode;
import com.shortlink.common.exception.AbstractException;
import lombok.Data;

import java.io.Serializable;
import java.util.Optional;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
public class ResponseResult<T> implements Serializable {
    private Integer code;
    private String msg;
    private T data;

    public ResponseResult() {
        this.code = AppHttpCodeEnum.SUCCESS.getCode();
        this.msg = AppHttpCodeEnum.SUCCESS.getMsg();
    }

    public ResponseResult(Integer code, T data) {
        this.code = code;
        this.data = data;
    }

    public ResponseResult(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public ResponseResult(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public static ResponseResult errorResult(int code, String msg) {
        ResponseResult result = new ResponseResult();
        return result.error(code, msg);
    }
    public static ResponseResult okResult() {
        ResponseResult result = new ResponseResult();
        return result;
    }
    public static ResponseResult okResult(int code, String msg) {
        ResponseResult result = new ResponseResult();
        return result.ok(code, null, msg);
    }

    public static ResponseResult okResult(Object data) {
        ResponseResult result = setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS, AppHttpCodeEnum.SUCCESS.getMsg());
        if(data!=null) {
            result.setData(data);
        }
        return result;
    }

    public static ResponseResult errorResult(IErrorCode enums){
        return setAppHttpCodeEnum(enums,enums.getMsg());
    }

    public static ResponseResult errorResult(IErrorCode enums, String msg){
        return setAppHttpCodeEnum(enums,msg);
    }

    /**
     * 通过 {@link AbstractException} 构建失败响应
     */
    public static ResponseResult errorResult(AbstractException abstractException) {
        Integer errorCode = Optional.ofNullable(abstractException.getErrorCode())
                .orElse(AppHttpCodeEnum.SERVICE_ERROR.getCode());
        String errorMessage = Optional.ofNullable(abstractException.getErrorMessage())
                .orElse(AppHttpCodeEnum.SERVICE_ERROR.getMsg());
        return ResponseResult.okResult(errorCode,errorMessage);
    }

    /**
     * 构建服务端失败响应
     */
    public static ResponseResult errorResult() {
//        return new Result<Void>()
//                .setCode(BaseErrorCode.SERVICE_ERROR.code())
//                .setMessage(BaseErrorCode.SERVICE_ERROR.message());
        return ResponseResult.okResult(AppHttpCodeEnum.SERVICE_ERROR.getCode()
                ,AppHttpCodeEnum.SERVICE_ERROR.getMsg());
    }

    public static ResponseResult setAppHttpCodeEnum(IErrorCode enums){
        return okResult(enums.getCode(),enums.getMsg());
    }

    private static ResponseResult setAppHttpCodeEnum(IErrorCode enums, String msg){
        return okResult(enums.getCode(),msg);
    }

    public ResponseResult<?> error(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
        return this;
    }

    public ResponseResult<?> ok(Integer code, T data) {
        this.code = code;
        this.data = data;
        return this;
    }

    public ResponseResult<?> ok(Integer code, T data, String msg) {
        this.code = code;
        this.data = data;
        this.msg = msg;
        return this;
    }

    public ResponseResult<?> ok(T data) {
        this.data = data;
        return this;
    }

}